package com.augurit.wf.mgmt.web;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.jbpm.pvm.internal.history.model.HistoryProcessInstanceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springside.modules.orm.Page;
import org.springside.modules.web.struts2.Struts2Utils;

import com.augurit.common.base.action.CrudActionSupport;
import com.augurit.common.base.action.ExtBaseAction;
import com.augurit.common.base.action.ExtCrudActionSupport;
import com.augurit.common.util.ExtUtils;
import com.augurit.common.util.lang.StringUtils;
import com.augurit.wf.common.constant.WfConstant;
import com.augurit.wf.common.entity.Jbpm4Execution;
import com.augurit.wf.common.entity.Jbpm4Task;
import com.augurit.wf.common.form.TraceRecord;
import com.augurit.wf.common.form.jbpm.Jbpm4TaskForm;
import com.augurit.wf.common.service.IWfService;
import com.augurit.wf.common.util.WfUtils;
import com.augurit.wf.mgmt.service.IWfProcessInstanceService;
import com.augurit.wf.mgmt.web.form.Jbpm4HistActInstForm;
import com.augurit.wf.mgmt.web.form.Jbpm4VariableForm;
import com.augurit.wf.mgmt.web.form.ProcInstBasicInfo;
import com.augurit.wf.mgmt.web.form.WfActivityInstanceForm;
import com.augurit.wf.mgmt.web.form.WfProcessInstanceForm;

@SuppressWarnings("serial")
@Results({
	@Result(name = CrudActionSupport.RELOAD, location = "wf-process-instance.action", type = "redirect"),
	@Result(name = CrudActionSupport.SUCCESS, location = "/wf/mgmt/process-instance/process-instance-mgmt.jsp")
})
public class WfProcessInstanceAction extends ExtCrudActionSupport<WfProcessInstanceForm> {

	private WfProcessInstanceForm form;
	private Page<WfProcessInstanceForm> page = new Page<WfProcessInstanceForm>(15);
	
	@Autowired
	private IWfProcessInstanceService wfProcessInstanceService;
	
	@Autowired
	private IWfService wfService;
	
	private WfActivityInstanceForm activityInstanceForm;

	private Long actInstDbid;//活动实例dbid
	
	private String outcome;
	
	private Jbpm4HistActInstForm actInstForm;
	
	private String assignee;
	
	private Long taskDbid;
	
	private Jbpm4TaskForm jbpm4TaskForm;
	
	@Override
	public String list() throws Exception {
		ExtUtils.initPageFromExtGridParam(ExtBaseAction.getRequest(), page);
		wfProcessInstanceService.search(page, form);
		ExtBaseAction.extRenderGridJson(page);
		return null;
	}
	
	/**
	 * 启动流程实例
	 * @return
	 * @throws Exception
	 */
	public String startProcessInstance() throws Exception {
		try{
			Map<String, Object> params = new HashMap<String, Object>();
			params.put(WfConstant.VAR_SYS_STARTER, this.getLoginUserName());
			
			wfService.startProcessInstance(form.getProcessDefinitionKey(), form.getProcessDefinitioVersion(), params);
			ExtBaseAction.extRenderSuccess();
		}
		catch(Exception e){
			e.printStackTrace();
			WfUtils.renderWfFailtureJson("");
		}
		return null;
	}
	
	
	//******************流程实例控制  开始******************
	/**
	 * 删除流程实例
	 * @param processInstanceId
	 * @return
	 */
	public String deleteProcessInstance()throws Exception{
		boolean success = false;
		if(form != null && form.getId() != null)
			success = this.wfProcessInstanceService.deleteProcessInstance(form.getId());
		String msg = success ? "成功删除任务实例" : "该流程实例不能删除";
		Struts2Utils.renderText(msg);
		return null;
	}
	
	/**
	 * 挂起流程实例
	 * @param processInstanceId
	 * @return
	 */
	public String suspendProcessInstance()throws Exception{
		boolean success = false;
		if(form != null && form.getId() != null)
			success = this.wfProcessInstanceService.suspendProcessInstance(form.getId());
		String msg = success ? "成功挂起任务实例" : "该流程实例不能挂起";
		Struts2Utils.renderText(msg);
		return null;
	}
	
	
	/**
	 * 恢复流程实例
	 * @param processInstanceId
	 * @return
	 */
	public String recoveryProcessInstance()throws Exception{
		boolean success = false;
		if(form != null && form.getId() != null){
			success = this.wfProcessInstanceService.recoveryProcessInstance(form.getId());
		}
		String msg = success ? "成功恢复任务实例" : "该流程实例不能恢复";
		Struts2Utils.renderText(msg);
		return null;
	}
	
	/**
	 * 结束流程实例
	 * @param processInstanceId
	 * @return
	 */
	public String endProcessInstance()throws Exception{
		boolean success = false;
		if(form != null && form.getId() != null){
			success = this.wfProcessInstanceService.endProcessInstance(form.getId());
		}
		String msg = success ? "成功结束任务实例" : "该流程实例不能结束";
		Struts2Utils.renderText(msg);
		return null;
	}
	
	/**
	 * 获取指定节点的历史意见
	 * @param processInstanceId
	 * @param activityName
	 * @return
	 */
	public String getActInst() throws Exception{
		if(form != null && form.getId() != null && StringUtils.isNotBlank(form.getActivityName())){
			List<TraceRecord> list = wfProcessInstanceService.getTraceRecord(form.getId(),form.getActivityName());
			String resultXML = this.renderXml(list, "node", TraceRecord.class);
			WfProcessInstanceAction.renderXml(resultXML);
		}
		return null;
	}
	
	//获取流程实例基本信息
	public String getProcInstBasicInfo() throws Exception{
		if(form != null && form.getId() != null){
			ProcInstBasicInfo basicInfo= wfProcessInstanceService.getProcInstBasicInfo(form.getId());
			if(basicInfo == null)
				basicInfo = new ProcInstBasicInfo();
			WfProcessInstanceAction.extRenderFormJson(basicInfo);
		}
		return null;
	}
	
	//保存流程实例基本信息
	public String saveProcDuedate() throws Exception{
		if(form != null && form.getId() != null && form.getProcessDuedate() != null){
			wfProcessInstanceService.savetProcDuedate(form);
			WfProcessInstanceAction.extRenderSuccess();
		}
		return null;
	}
	
	//获取流程实例变量
	public String getProcInstVariables()throws Exception{
		if(form != null && form.getId() != null){
			List<Jbpm4VariableForm> list = wfProcessInstanceService.getProcInstVariables(form.getId());
			WfProcessInstanceAction.extRenderGridJson(list);
		}
		return null;
	}
	
	//******************流程实例控制  结束******************
	
	//******************活动实例控制  开始******************
	
	/**
	 * 根据流程实例ID获取当前流程实例中所有活动的实例
	 * @return
	 */
	public String getActivityInstances(){
		if(form != null || taskDbid != null){
			//获取当前流程实例的基本信息
			HistoryProcessInstanceImpl hisProcessInstance = null;
			
			if(form.getId() != null && !"".equals(form.getId())){
				hisProcessInstance = wfProcessInstanceService.getHisProcessInstancesById(form.getId());
			}else if(taskDbid != null){
				hisProcessInstance = wfProcessInstanceService.getProcessInstancesByTaskDbid(taskDbid.toString());
			}
			
			if(hisProcessInstance == null)
				return null;
			
			//获取当前流程实例的历史活动节点集合
			List<WfActivityInstanceForm> wfActivityInstanceForms = wfProcessInstanceService.getActsByProcInstId(hisProcessInstance.getProcessInstanceId());
			String historyActivitysXML = this.renderXml(wfActivityInstanceForms, "node", WfActivityInstanceForm.class);
			
			//获取当前活动节点集合
			List<Jbpm4Execution> currentActivityins = wfProcessInstanceService.getCurrentActivityInstancesByProcessInstanceId(hisProcessInstance.getDbid());
			String currentActivityInstancesXML = this.renderXml(currentActivityins, "activityNodes", Jbpm4Execution.class);
			
			WfProcessInstanceAction.renderXml("<results>"+historyActivitysXML + currentActivityInstancesXML+"</results>");
		}
		return null;
	}
	/**
	 * 根据流程实例ID获取当前流程实例中所有活动的实例，JSON格式作为流输出
	 * @return
	 */
	public String getActInstsByActivityName(){
		if(form != null && form.getId() != null && StringUtils.isNotBlank(form.getActivityName())){
			List<WfActivityInstanceForm> result = wfProcessInstanceService.getActInstsByActivityName(form);
			ExtBaseAction.extRenderGridJson(result);
		}
		return null;
	}
	
	/**
	 * 根据活动实例ID获取Jbpm4HistActInst活动实例对象
	 *@param actInstDbid
	 *@return 
	 */
	public String getActInstByDbid()throws Exception{
		if(actInstDbid != null){
			Jbpm4HistActInstForm jbpm4HistActInstForm = wfProcessInstanceService.getActInstByDbid(actInstDbid);
			if(jbpm4HistActInstForm != null)
				WfProcessInstanceAction.extRenderFormJson(jbpm4HistActInstForm);
		}
		return null;
	}
	
	/**
	 * 根据活动实例ID获取活动实例任务列表
	 * @param actInstDbid
	 * @return
	 */
	public String getTasksByActInstDbid() throws Exception{
		if(actInstDbid != null){
			List<Jbpm4TaskForm> list = wfProcessInstanceService.getTasksByActInstDbid(actInstDbid);
			WfProcessInstanceAction.extRenderGridJson(list);
		}
		return null;
	}
	
	/**
	 * 根据活动实例ID挂起活动实例
	 * @return
	 * @throws Exception
	 */
	public String suppendActInst()throws Exception{
		boolean success = false;
		if(actInstDbid != null){
			success = wfProcessInstanceService.suppendActInst(actInstDbid);
		}
		String msg = success ? "成功挂起活动实例" : "该活动实例不能挂起";
		Struts2Utils.renderText(msg);
		return null;
	}
	
	/**
	 * 根据活动实例ID恢复活动实例
	 * @return
	 * @throws Exception
	 */
	public String recoveryActInst()throws Exception{
		boolean success = false;
		if(actInstDbid != null){
			success = wfProcessInstanceService.recoveryActInst(actInstDbid);
		}
		String msg = success ? "成功恢复活动实例" : "该活动实例不能恢复";
		Struts2Utils.renderText(msg);
		return null;
	}
	
	/**
	 * 回退活动实例
	 * @return
	 */
	public String rollbackActivityInstance() throws Exception{
		
		boolean result = wfProcessInstanceService.rollbackActivityInstance(activityInstanceForm.getExecutionId());
		
		if(result)
			WfProcessInstanceAction.renderText("回退成功!");
		else
			WfProcessInstanceAction.renderText("不能回退!");
		return null;
	}
	
	//******************活动实例控制  结束******************
	
	//******************工作项控制  开始******************
	
	//取消代办
	public String cancelAgentTask() throws Exception{
		if(taskDbid != null ){
			wfProcessInstanceService.cancelAgentTask(taskDbid);
			WfProcessInstanceAction.extRenderSuccess();
		}
		return null;
	}
	
	public String getTaskByDbid() throws Exception{
		if(taskDbid != null ){
			jbpm4TaskForm = wfProcessInstanceService.getTaskByDbid(taskDbid);
			WfProcessInstanceAction.extRenderFormJson(jbpm4TaskForm);
		}
		return null;
	}
	

	//创建工作项,只有多工作项的任务活动实例才可以动态创建工作项
	public String addSubTask()throws Exception{
		boolean success = false;
		if(actInstDbid != null && assignee != null && assignee.trim().length()>0){
			success = wfProcessInstanceService.addSubTask(actInstDbid, assignee);
		}
		String msg = success ? "成功增加工作项" : "该活动实例不能增加工作项";
		Struts2Utils.renderText(msg);
		return null;
	}
	
	//删除工作项,只有多工作项的任务活动实例才可以动态删除工作项
	public String delSubTask()throws Exception{
		boolean success = false;
		if(taskDbid != null){
			success = wfProcessInstanceService.delSubTask(taskDbid.toString());
		}
		String msg = success ? "成功删除工作项" : "该工作项不能删除";
		Struts2Utils.renderText(msg);
		return null;
	}
	
	/**
	 * 修改工作项
	 * @return
	 */
	public String updateTask()throws Exception{
		try {
			Jbpm4Task oldJbpm4Task = wfProcessInstanceService.getJbpm4TaskByDbid(jbpm4TaskForm.getTaskInstDbid());
			
			oldJbpm4Task.setDuedate(jbpm4TaskForm.getDuedate());
			oldJbpm4Task.setHandleCommentsTime(jbpm4TaskForm.getHandleCommentsTime());
			oldJbpm4Task.setHandleComments(jbpm4TaskForm.getHandleComments());
			oldJbpm4Task.setAssignee(jbpm4TaskForm.getAssignee());
			oldJbpm4Task.setAssigneeName(jbpm4TaskForm.getAssigneeName());
			oldJbpm4Task.setAgent(jbpm4TaskForm.getAgent());
			oldJbpm4Task.setAgentName(jbpm4TaskForm.getAgentName());
			oldJbpm4Task.setAgentStartDate(jbpm4TaskForm.getAgentStartDate());
			oldJbpm4Task.setAgentEndDate(jbpm4TaskForm.getAgentEndDate());
			
			boolean result = wfProcessInstanceService.updateTask(oldJbpm4Task);
			
			if(result)
				Struts2Utils.renderText("success");
			else
				Struts2Utils.renderText("failure");
		} catch (Exception e) {
			Struts2Utils.renderText("failure");
			e.printStackTrace();
			throw e;
		}
		
		return null;
	}
	
	//******************工作项实例控制  开始******************
	@Override
	public String delete() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	protected void prepareModel() throws Exception {
		if (form == null)
			form = new WfProcessInstanceForm();
	}

	@Override
	public String save() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	public WfProcessInstanceForm getModel() {
		// TODO Auto-generated method stub
		return form;
	}

	public Page<WfProcessInstanceForm> getPage() {
		return page;
	}

	public void setPage(Page<WfProcessInstanceForm> page) {
		this.page = page;
	}

	public WfProcessInstanceForm getForm() {
		return form;
	}

	public void setForm(WfProcessInstanceForm form) {
		this.form = form;
	}

	public WfActivityInstanceForm getActivityInstanceForm() {
		return activityInstanceForm;
	}

	public void setActivityInstanceForm(WfActivityInstanceForm activityInstanceForm) {
		this.activityInstanceForm = activityInstanceForm;
	}

	public Long getActInstDbid() {
		return actInstDbid;
	}

	public void setActInstDbid(Long actInstDbid) {
		this.actInstDbid = actInstDbid;
	}

	public String getOutcome() {
		return outcome;
	}

	public void setOutcome(String outcome) {
		this.outcome = outcome;
	}

	public Jbpm4HistActInstForm getActInstForm() {
		return actInstForm;
	}

	public void setActInstForm(Jbpm4HistActInstForm actInstForm) {
		this.actInstForm = actInstForm;
	}

	public String getAssignee() {
		return assignee;
	}

	public void setAssignee(String assignee) {
		this.assignee = assignee;
	}

	public Long getTaskDbid() {
		return taskDbid;
	}

	public void setTaskDbid(Long taskDbid) {
		this.taskDbid = taskDbid;
	}

	public Jbpm4TaskForm getJbpm4TaskForm() {
		return jbpm4TaskForm;
	}

	public void setJbpm4TaskForm(Jbpm4TaskForm jbpm4TaskForm) {
		this.jbpm4TaskForm = jbpm4TaskForm;
	}

}
